/**
 * Copyright (c) 2010 Basil Shikin, BugStat Project
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package org.bugstat.gui.wizard;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;

import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;

import net.miginfocom.swing.MigLayout;

import org.bugstat.exporters.BugExporer;
import org.bugstat.exporters.ConnectionManager.DatabaseType;
import org.bugstat.gui.PropertyTracker;
import org.bugstat.gui.UIStrings;
import org.jdesktop.swingx.JXBusyLabel;
import org.pietschy.wizard.PanelWizardStep;

/**
 * This class is used to select tracking system and database type. It has following layout:
 * <pre>
 *     +--------------------------+
 *     | TS_TYPE:     |TS TYPE *| |
 *     | DB_TYPE:     |DB_TYPE *| |
 *     | DB_ADDRESS:  |ADR| |PRT| |
 *     | DB_NAME      |NAME|      |
 *     | DB_USER:     |USER|      |
 *     | DB_PASS:     |PASS|      |
 *     |                          |
 *     | /*BUSY_LBL/              |
 *     +--------------------------+
 * </pre>
 * 
 * @author Basil Shikin
 *
 */
public class SelectTrackingSystemPage
    extends PanelWizardStep
{
    private static final long serialVersionUID = 1L;

    private final PropertyTracker tracker;
    
    private final JComboBox       systemType;
    private final JComboBox       databaseType;
    private final JTextField      databaseHost;
    private final JTextField      databasePort;
    private final JTextField      databaseName;
    private final JTextField      databaseUsername;
    private final JPasswordField  databasePassword;
    
    private final JXBusyLabel     statusLabel;
    private final JLabel          messageLabel;

    public SelectTrackingSystemPage()
    {
        tracker = new PropertyTracker();
        
        setName( UIStrings.TEXT_BUG_TRACKER_PROPERTIES );
        setSummary( UIStrings.TEXT_BUG_TRACKER_SUMMARY );
        
        final JLabel systemTypeLabel = new JLabel( UIStrings.TEXT_BUG_TRACKER_TYPE + ":");
        systemType = new JComboBox();
        systemType.setRenderer( new BugExporterRenderer() );

        final JLabel databaseOptionsLabel = new JLabel( UIStrings.TEXT_DATABASE_OPTIONS );
        
        final JLabel databaseTypeLabel = new JLabel( UIStrings.TEXT_TYPE + ":");
        databaseType = new JComboBox();
        databaseType.setRenderer( new DatabaseTypeRenderer() );
        
        final JLabel databaseAddressLabel = new JLabel( UIStrings.TEXT_ADDRESS+ ":");
        databaseHost = new JTextField();
        trackComponent( databaseHost, "bugstat.gui.dbhost", "localhost");
        
        databasePort = new JTextField();
        trackComponent( databasePort, "bugstat.gui.dbport", "3306" );
        
        final JLabel databaseNameLabel = new JLabel( UIStrings.TEXT_DATABASE_NAME + ":");
        databaseName = new JTextField();
        trackComponent( databaseName, "bugstat.gui.dbname", "bugs" );
        
        final JLabel databaseUsernameLabel = new JLabel( UIStrings.TEXT_USERNAME + ":");
        databaseUsername = new JTextField( "bugs" );
        trackComponent( databaseUsername, "bugstat.gui.dbusername", "bugs" );
        
        final JLabel databasePasswordLabel = new JLabel( UIStrings.TEXT_PASSWORD + ":");
        databasePassword = new JPasswordField();
        
        
        statusLabel = new JXBusyLabel( new Dimension(16,16) );
        statusLabel.setVisible( false );
        
        messageLabel = new JLabel();
        messageLabel.setVisible( false );
         
        setLayout( new MigLayout("fill", "9[right]5[grow]9", "9[]18[]7[]7[]7[]7[]7[]11[]push") );
        
        add( systemTypeLabel,      "");
        add( systemType,           "growx, wrap");
        
        add( databaseOptionsLabel, "spanx 2, align left, wrap");

        add( databaseTypeLabel,    "gap 18, align right" );
        add( databaseType,         "growx, wrap" );

        add( databaseAddressLabel, "gap 18" );
        add( databaseHost,         "growx, split" );
        add( databasePort,         "wmin 40, wrap" );
        
        add( databaseNameLabel,    "gap 18" );
        add( databaseName,         "growx, wrap" );
        
        add( databaseUsernameLabel,    "gap 18" );
        add( databaseUsername,         "growx, wrap" );
        
        add( databasePasswordLabel,    "gap 18" );
        add( databasePassword,         "growx, wrap" );
        
        add( statusLabel,       "spanx 2, h 16!, hidemode 2, align center, wrap" );
        add( messageLabel,      "spanx 2, growy, hidemode 2, align center, wrap" );
        
        setComplete( true );
    }
    

    @Override
    public void setBusy(boolean busy)
    {
        super.setBusy(busy);
        
        statusLabel.setVisible( busy );
        statusLabel.setBusy( busy );
        
        if ( busy )
        {
            messageLabel.setVisible( false );
            statusLabel.setText( UIStrings.TEXT_CHECKING_CONNECTION + "..." );
        }
    }
    
    public void setExporters(Collection<BugExporer> exporters)
    {
        if ( exporters == null ) throw new IllegalArgumentException( "No exporters specified");
        
        systemType.setModel( new DefaultComboBoxModel( exporters.toArray() ) );
        trackComponent( systemType, "dbtype", exporters.iterator().next() );
    }

    public void setDatabaseTypes(Collection<DatabaseType> databaseTypes)
    {
        if ( databaseTypes == null ) throw new IllegalArgumentException( "No database types specified");
        
        databaseType.setModel( new DefaultComboBoxModel( databaseTypes.toArray() ) );
        trackComponent( databaseType, "dbtype", DatabaseType.MY_SQL);
    }
    
    public void setErrorMessage( final String message)
    {
        final boolean hasError = message != null;
        
        statusLabel.setVisible( false );
        statusLabel.setBusy( false );
        
        messageLabel.setVisible( hasError );
        messageLabel.setText( "<html>" + message );
    }
    
    private static class BugExporterRenderer 
        extends DefaultListCellRenderer 
    {
        private static final long serialVersionUID = 8358690885647659752L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            if ( value instanceof BugExporer )
            {
                final BugExporer exporer = (BugExporer)value;
                
                value = exporer.getBugTrackerName();
            }
            
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    }
    
    private static class DatabaseTypeRenderer 
        extends DefaultListCellRenderer 
    {
        private static final long serialVersionUID = -3841910553799695820L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
        {
            if ( value == DatabaseType.MY_SQL )
            {
                value = UIStrings.TEXT_MYSQL;
            }
            else if ( value == DatabaseType.ORACLE )
            {
                value = UIStrings.TEXT_ORACLE;
            }
            else if ( value == DatabaseType.MSSQL )
            {
                value = UIStrings.TEXT_MS_SQL;
            }
            else
            {
                value = UIStrings.TEXT_UNKNOWN;
            }
            
            return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        }
    }

    public String getDatabaseName()
    {
        return databaseName.getText();
    }

    public String getDatabaseHostname()
    {
        return databaseHost.getText();
    }

    public String getDatabasePort()
    {
        return databasePort.getText();
    }

    public String getDatabaseUsername()
    {
        return databaseUsername.getText();
    }

    public String getDatabasePassword()
    {
        return new String( databasePassword.getPassword() );
    }

    public DatabaseType getDatabaseType()
    {
        return (DatabaseType)databaseType.getSelectedItem();
    }
    
    public BugExporer getSelectedExporter()
    {
        return (BugExporer)systemType.getSelectedItem();
    }

    private void trackComponent(JTextComponent field, String key, String defaultValue)
    {
        final String value = tracker.get( key, defaultValue);
        field.setText( value );
        
        tracker.trackTextComponent( field, key);
    }

    private void trackComponent(final JComboBox comboBox, final String key, final Object defaultValue)
    {
        final int defaultIndex = ((DefaultComboBoxModel)comboBox.getModel()).getIndexOf( defaultValue );
        final int selectedIndex = tracker.get( key, defaultIndex );
        
        comboBox.setSelectedIndex( selectedIndex );
        
        comboBox.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {
                tracker.put( key, comboBox.getSelectedIndex() );
            }
        });
    }

}
